<template>
  <div class="main-layout">
    <!-- 左侧：控制面板 -->
    <div class="car-control">
      <h2>小车遥控台</h2>
      <div class="grid">
        <button v-on="pressHandlers('LeftRotate')">左旋转</button>
        <button v-on="pressHandlers('Front')">前进</button>
        <button v-on="pressHandlers('RightRotate')">右旋转</button>
        <button v-on="pressHandlers('Left')">左移</button>
        <button @click="sendCmd('Stop')" class="stop">停车</button>
        <button v-on="pressHandlers('Right')">右移</button>
        <button @click="sendCmd('Brake')">刹车</button>
        <button v-on="pressHandlers('After')">后退</button>
        <button @click="sendCmd('Brake')">刹车</button>
      </div>
      <div class="status">
        <span>WebSocket连接：
          <b :style="{ color: connected ? 'green' : 'red' }">
            {{ connected ? '已连接' : '未连接' }}
          </b>
        </span>
        <p>反馈：{{ serverMsg }}</p>
      </div>
      <!-- 语音控制按钮 -->
      <button class="voice-btn" @click="startSpeechRecognition">🎤 语音控制</button>
    </div>

    <!-- 右侧：视频显示 ✅ 只有在 videoReady 才渲染 -->
    <div class="video-box" v-if="videoReady">
      <h2 style="font-weight:500;font-size:18px;margin-bottom:12px;">摄像头画面</h2>
      <img :src="videoUrl" class="video-img" />
      <!-- 🔽 环境数据展示区域（新加） -->
      <div class="sensor-info">
        <h3>环境信息</h3>
        <p>光照强度：{{ sensorData.illumination ?? 'null' }}</p>
        <p>烟雾浓度：{{ sensorData.smoke ?? 'null' }}</p>
        <p>PM2.5：{{ sensorData.pm25 ?? 'null' }}</p>
        <p>采集时间：{{ sensorData.time ?? 'null' }}</p>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'

/* ---------- 新增：环境数据 --------- */
const sensorData = ref({});

/* ---------- 自动定时刷新环境数据 --------- */
let fetchTimer = null;
async function fetchSensorData() {
  try {
    // 这里端口和地址要与你后端接口一致，如果端口被代理，可以写/api/iot/latest
    const res = await fetch("http://localhost:8080/iot/latest");
    if (!res.ok) throw new Error("请求失败");
    const data = await res.json();
    sensorData.value = data;
  } catch (err) {
    sensorData.value = {}; // 清空数据
  }
}
onMounted(() => {
  fetchSensorData();
  fetchTimer = setInterval(fetchSensorData, 2000); // 2秒刷新一次
});
onBeforeUnmount(() => {
  fetchTimer && clearInterval(fetchTimer);
});

/* ---------- WebSocket 连接 ---------- */
const ws          = ref(null)
const connected   = ref(false)
const serverMsg   = ref('')
const videoReady  = ref(false)
const videoUrl    = ref("http://192.168.98.62:6500/video_feed") // 这里改为你的摄像头流地址

function connectWS () {
  ws.value = new WebSocket('ws://localhost:8080/ws/car')

  ws.value.onopen    = () => { connected.value = true;  serverMsg.value = 'WebSocket已连接'  }
  ws.value.onclose   = () => { connected.value = false; serverMsg.value = 'WebSocket已断开' }
  ws.value.onerror   = () => { connected.value = false; serverMsg.value = 'WebSocket出错'   }
  ws.value.onmessage = e  => { serverMsg.value = e.data }

  ws.value.onmessage = e => {
    serverMsg.value = e.data
    if (e.data.includes('初始化成功') || e.data.includes('初始化已完成')) {
      videoReady.value = true          // 打开视频
    }
  }
}
onMounted(connectWS)
onBeforeUnmount(() => ws.value && ws.value.close())

/* ---------- 发送指令的通用函数 ---------- */
function sendCmd (cmd) {
  if (ws.value && connected.value) {
    ws.value.send(cmd)
  } else {
    serverMsg.value = 'WebSocket未连接，无法发送指令'
  }
}

/* ---------- 按住运动 / 松手停止 ---------- */
let repeatTimer = null      // 定时器 ID
const REPEAT_MS = 200       // 按住期间，多久重发一次指令（ms）

function pressHandlers (cmd) {
  return {
    mousedown:  () => startHold(cmd),
    touchstart: e => { e.preventDefault(); startHold(cmd) },

    mouseup:    stopHold,
    mouseleave: stopHold,
    touchend:   stopHold,
    touchcancel:stopHold
  }
}

function startHold (cmd) {
  sendCmd(cmd)                           // 先发一次
  repeatTimer = setInterval(() => sendCmd(cmd), REPEAT_MS)
}

function stopHold () {
  clearInterval(repeatTimer)
  repeatTimer = null
  sendCmd('Stop')                        // 松手立即停
}

// 语音 → 指令 映射
const voiceMap = {
  "前进": "Front",
  "前": "Front",
  "后退": "After",
  "后": "After",
  "左转": "LeftRotate",
  "右转": "RightRotate",
  "左移": "Left",
  "右移": "Right",
  "停止": "Stop",
  "停": "Stop",
  "刹车": "Brake"
};

// 语音识别入口
function startSpeechRecognition() {
  if (!('webkitSpeechRecognition' in window)) {
    alert("你的浏览器不支持语音识别，请使用 Chrome 浏览器！");
    return;
  }

  const recognition = new webkitSpeechRecognition();
  recognition.continuous = false;
  recognition.lang = "zh-CN";
  recognition.interimResults = false;

  recognition.onstart = () => {
    serverMsg.value = "🎤 正在聆听...";
  };

  recognition.onresult = (event) => {
    const text = event.results[0][0].transcript.trim();
    serverMsg.value = "🗣️ 识别结果：" + text;

    for (const [key, value] of Object.entries(voiceMap)) {
      if (text.includes(key)) {
        sendCmd(value);
        serverMsg.value += ` → 指令: ${value}`;
        return;
      }
    }

    serverMsg.value += " ❌ 未识别到有效指令";
  };

  recognition.onerror = () => {
    serverMsg.value = "❌ 语音识别出错";
  };

  recognition.start();
}
</script>

<style scoped>
/* 总布局：左右排列，移动端自适应为上下 */
.main-layout {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  gap: 28px;
  margin-top: 28px;
  flex-wrap: wrap;
}

.car-control {
  min-width: 320px;
  max-width: 350px;
  margin: 0 auto;
  padding: 32px 18px 18px 18px;
  border-radius: 18px;
  background: #fafbfc;
  box-shadow: 0 2px 12px #eee;
  text-align: center;
  flex: 1 1 320px;
}
.grid {
  display: grid;
  grid-template-columns: repeat(3, 70px);
  gap: 12px;
  justify-content: center;
  margin-bottom: 20px;
}
button {
  padding: 14px 0;
  font-size: 15px;
  border-radius: 10px;
  border: 1px solid #ccc;
  cursor: pointer;
  background: #f7f9fa;
  transition: background 0.2s;
}
button.stop {
  background: #ff5353;
  color: #fff;
  font-weight: bold;
  font-size: 17px;
}
button:active {
  background: #d5f0f9;
}
.status {
  margin-top: 18px;
  font-size: 14px;
}
.voice-btn {
  margin-top: 18px;
  width: 90%;
  font-size: 15px;
  background: #50b8fc;
  color: #fff;
  border: none;
}
.video-box {
  min-width: 260px;
  max-width: 360px;
  background: #fff;
  border-radius: 14px;
  box-shadow: 0 2px 8px #eee;
  padding: 16px 8px 18px 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.video-img {
  width: 320px;
  height: 240px;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid #eee;
  box-shadow: 0 1px 5px #eee;
}
@media (max-width: 900px) {
  .main-layout {
    flex-direction: column;
    align-items: center;
  }
  .video-box { margin-top: 28px; }
}
.sensor-info {
  margin-top: 24px;
  padding: 16px 18px 8px 18px;
  border-radius: 8px;
  background: #fafbfc;
  box-shadow: 0 2px 6px #f2f4f7;
  font-size: 15px;
  text-align: left;
  min-width: 220px;
  max-width: 340px;
}
.sensor-info h3 {
  margin: 0 0 8px 0;
  font-weight: 600;
  font-size: 17px;
  text-align: center;
}
.sensor-info p {
  margin: 4px 0;
  font-size: 15px;
  line-height: 1.5;
}
</style>